package com.study.juc.threadpool;

import java.util.LinkedList;

public class LinkedRunnableQueue implements RunnableQueue{
    
    private final int limit;
    private LinkedList<Runnable> runnableList = new LinkedList<>();
    
    private final DenyPolicy denyPolicy;

    private final ThreadPool pool;


    public LinkedRunnableQueue(int limit, DenyPolicy denyPolicy, ThreadPool pool) {
        this.limit = limit;
        this.denyPolicy = denyPolicy;
        this.pool = pool;
    }

    @Override
    public void offer(Runnable runnable) {
        synchronized (runnableList){
            if(runnableList.size() >= limit){
                if(denyPolicy !=null){
                    denyPolicy.reject(runnable,pool);
                }
            }else {
                runnableList.addLast(runnable);
                runnableList.notifyAll();
            }
        }
    }

    @Override
    public Runnable take() throws InterruptedException{
        synchronized (runnableList){
            while(runnableList.isEmpty()){
                try {
                    runnableList.wait();
                } catch (InterruptedException e) {
                    throw  e;
                }
            }
            Runnable runnable = runnableList.removeFirst();
            return  runnable;
        }
    }

    @Override
    public int size() {
        synchronized (runnableList){
            return runnableList.size();
        }
    }
}
